#include "usb_configure.h"
#include "stdio.h"
#include "string.h"

void UsbConfigTask(void * pvParameters)
{
	RTC_DateTypeDef  date;
	RTC_TimeTypeDef  time;
	uint8_t i;
	uint8_t i2;
	uint8_t *p8;
	uint32_t address;
	sParamSecondary paramSecondary;
	sParamGeneral paramGeneral;
	/* USB init */
	USBConfig();

	for(;;)
	{
		/* USB hanler */
		HAL_PCD_IRQHandler(&hpcd);

		if(usbStatusBuf != 0)
		{
			i = 0;
			switch(usbBuf[1])
			{
			case E_USB_OPERATION_GET_SYS_PARAM:
				i = 0;
				usbBuf[i++] = REPORT_ID_2;
				/* marker operaion */
				usbBuf[i++] = E_USB_OPERATION_GET_SYS_PARAM;
				/* Read General parameters */
				Flash_M25P64_Read_Buffer((uint8_t*)&paramGeneral, 0, sizeof(paramGeneral));
				/* version software*/
				usbBuf[i++] = ((VERSION_SOFTWARE & 0xFF000000)>>24);
				usbBuf[i++] = ((VERSION_SOFTWARE & 0x00FF0000)>>16);
				usbBuf[i++] = ((VERSION_SOFTWARE & 0x0000FF00)>>8);
				usbBuf[i++] = ( VERSION_SOFTWARE & 0x000000FF);
				/* id PLK */
				usbBuf[i++] = ((paramGeneral.id_plk & 0xFF000000)>>24);
				usbBuf[i++] = ((paramGeneral.id_plk & 0x00FF0000)>>16);
				usbBuf[i++] = ((paramGeneral.id_plk & 0x0000FF00)>>8);
				usbBuf[i++] = ( paramGeneral.id_plk & 0x000000FF);
				/* date time*/
				HAL_RTC_GetDate(&RtcHandle, &date, RTC_FORMAT_BIN);
				HAL_RTC_GetTime(&RtcHandle, &time, RTC_FORMAT_BIN);
				usbBuf[i++] = time.Seconds;
				usbBuf[i++] = time.Minutes;
				usbBuf[i++] = time.Hours;
				usbBuf[i++] = date.Date;
				usbBuf[i++] = date.Month;
				usbBuf[i++] = date.Year;
				break;

			case E_USB_OPERATION_WRITE_POLL_REQUEST:
				/* Inserting poll fields */
				/* usbBuf[2] == Leng Pack /
				 * usbBuf[3] ... usbBuf[Leng Pack] == user Data
				 * CRC calc automatic
				 */
				/* get used channel */
				modbusReq.channel = usbBuf[2];
				/* used baudrate */
				modbusReq.baudrate = usbBuf[3];
				for( i=0; i<usbBuf[4]; i++ )
					modbusReq.tx_buf[i] = usbBuf[5+i];
				modbusReq.txLeng = i;
				/* Poll !!! */
				modbusReq.state |= E_MODBUS_STATE_START_MANUAL;
				/* pause */
				while(modbusReq.state & E_MODBUS_STATE_START_MANUAL)
					vTaskDelay(10);
				/* Insert Reply Pack */
				i = 0;
				usbBuf[i++] = REPORT_ID_2;
				/* marker operaion */
				usbBuf[i++] = E_USB_OPERATION_WRITE_POLL_REQUEST;
				/* used channel */
				usbBuf[i++] = modbusReq.channel;
				/* CRC reply state */
				usbBuf[i++]  = modbusReq.crc_state;
				/* Reply leng */
				usbBuf[i++]  = modbusReq.rxLeng;
				/* copy reply buffer */
				for(i2=0; i2<modbusReq.rxLeng; i2++)
					usbBuf[i++] = modbusReq.rx_buf[i2];
				break;

			case E_USB_OPERATION_WRITE_POLL_REQUEST_RAW:
				modbusReq.channel = usbBuf[2];
				/* used baudrate */
				modbusReq.baudrate = usbBuf[3];
				for( i=0; i<usbBuf[4]; i++ )
					modbusReq.tx_buf[i] = usbBuf[5+i];
				modbusReq.txLeng = i;
				/* Poll !!! */
				modbusReq.state |= E_MODBUS_STATE_START_MANUAL;
				/* pause */
				while(modbusReq.state & E_MODBUS_STATE_START_MANUAL)
					vTaskDelay(10);
				/* Insert Reply Pack */
				i = 0;
				usbBuf[i++] = REPORT_ID_2;
				/* marker operaion */
				usbBuf[i++] = E_USB_OPERATION_WRITE_POLL_REQUEST;
				/* used channel */
				usbBuf[i++] = modbusReq.channel;
				/* CRC reply state */
				usbBuf[i++]  = modbusReq.crc_state;
				/* Reply leng */
				usbBuf[i++]  = modbusReq.rxLeng;
				/* copy reply buffer */
				for(i2=0; i2<modbusReq.rxLeng; i2++)
					usbBuf[i++] = modbusReq.rx_buf[i2];
				break;

			case E_USB_OPERATION_GET_PARAM_GENERAL:
				/* get Network parameters */
				/* marker operaion */
				usbBuf[i++] = REPORT_ID_2;
				usbBuf[i++] = E_USB_OPERATION_GET_PARAM_GENERAL;
				/* Read parameters */
				Flash_M25P64_Read_Buffer((uint8_t*)&paramGeneral, 0, sizeof(paramGeneral));
				/* Copy buffer */
				p8 = (uint8_t*)&paramGeneral;
				for(i2=0;i2<sizeof(paramGeneral);i2++)
				{
					usbBuf[i++] = (*p8);
					p8++;
				}
				break;

			case E_USB_OPERATION_GET_PARAM_POLL:
				usbBuf[i++] = REPORT_ID_2;
				usbBuf[i++] = E_USB_OPERATION_GET_PARAM_POLL;
				address = usbBuf[2];
				address = address <<8;
				address |= usbBuf[3];
				address = address <<8;
				address |= usbBuf[4];
				address = address <<8;
				address |= usbBuf[5];
				/* Read parameters */
				Flash_M25P64_Read_Buffer((uint8_t*)&paramSecondary, address, sizeof(paramSecondary));
				/* Copy buffer */
				p8 = (uint8_t*)&paramSecondary;
				for(i2=0;i2<sizeof(paramSecondary);i2++)
				{
					usbBuf[i++] = (*p8);
					p8++;
				}
				break;

			case E_USB_OPERATION_WRITE_PARAM_GENERAL:
				/* marker operaion */
				usbBuf[i++] = REPORT_ID_2;
				usbBuf[i++] = E_USB_OPERATION_WRITE_PARAM_GENERAL;
				address = usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				/* Erase All block */
				Flash_M25P64_EraseAll();
				/* copy buf */
				p8 = (uint8_t*)&paramGeneral;
				for(i2=0;i2<sizeof(paramGeneral);i2++)
				{
					*p8 = usbBuf[i++];
					p8++;
				}
				paramGeneral.final = FINAL_OK;
				FLASH_M25P64_Write_Buffer((uint8_t*)&paramGeneral, 0, sizeof(paramGeneral));
				break;

			case E_USB_OPERATION_WRITE_PARAM_POLL:
				usbBuf[i++] = REPORT_ID_2;
				usbBuf[i++] = E_USB_OPERATION_WRITE_PARAM_POLL;
				address = usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				address = address <<8;
				address |= usbBuf[i++];
				/* copy buf */
				p8 = (uint8_t*)&paramSecondary;
				for(i2=0;i2<sizeof(paramSecondary);i2++)
				{
					*p8 = usbBuf[i++];
					p8++;
				}
				paramSecondary.final = FINAL_OK;
				FLASH_M25P64_Write_Buffer((uint8_t*)&paramSecondary, address, sizeof(paramSecondary));
				break;

			case E_USB_OPERATION_WRITE_DATE_TIME:
				usbBuf[i++] = REPORT_ID_2;
				usbBuf[i++] = E_USB_OPERATION_WRITE_DATE_TIME;
				/* */
				date.Year 	= usbBuf[2];
				date.Month	= usbBuf[3];
				date.Date	= usbBuf[4];
				time.Hours	= usbBuf[5];
				time.Minutes = usbBuf[6];
				time.Seconds = usbBuf[7];
				/* Set DateTime */
				HAL_RTC_SetDate(&RtcHandle, &date, RTC_FORMAT_BIN);
				HAL_RTC_SetTime(&RtcHandle, &time, RTC_FORMAT_BIN);
				/* Get DateTime */
				HAL_RTC_GetDate(&RtcHandle, &date, RTC_FORMAT_BIN);
				HAL_RTC_GetTime(&RtcHandle, &time, RTC_FORMAT_BIN);
				usbBuf[i++] = time.Seconds;
				usbBuf[i++] = time.Minutes;
				usbBuf[i++] = time.Hours;
				usbBuf[i++] = date.Date;
				usbBuf[i++] = date.Month;
				usbBuf[i++] = date.Year;
				break;

			default : break;
			}

			LED_RED_0;
			/* Send Packet */
			USBD_CUSTOM_HID_SendReport((USBD_HandleTypeDef*)&USBD_Device, (uint8_t*)&usbBuf, sizeof(usbBuf));
			usbCounterPack = 0;
			usbStatusBuf = 0;
		}

		vTaskDelay(25);

		/* led off */
		LED_RED_1;
		LED_GREEN_1;
	}
}

